package scala.scalanative
package libc
import scalanative.unsafe._

/** tgmath.h binding ISO/IEC 9899:1999(C99)
 */
object tgmath extends tgmath

private[scalanative] trait tgmath {
  // real

  def fabs(x: CDouble): CDouble = math.fabs(x)
  def fabs(x: CFloat): CFloat = math.fabsf(x)
  def exp(x: CDouble): CDouble = math.exp(x)
  def exp(x: CFloat): CFloat = math.expf(x)
  def log(x: CDouble): CDouble = math.log(x)
  def log(x: CFloat): CFloat = math.logf(x)
  def pow(base: CDouble, exponent: CDouble): CDouble = math.pow(base, exponent)
  def pow(base: CFloat, exponent: CFloat): CFloat = math.powf(base, exponent)
  def sqrt(x: CDouble): CDouble = math.sqrt(x)
  def sqrt(x: CFloat): CFloat = math.sqrtf(x)
  def sin(x: CDouble): CDouble = math.sin(x)
  def sin(x: CFloat): CFloat = math.sinf(x)
  def cos(x: CFloat): CFloat = math.cosf(x)
  def cos(x: CDouble): CDouble = math.cos(x)
  def tan(x: CDouble): CDouble = math.tan(x)
  def tan(x: CFloat): CFloat = math.tanf(x)
  def asin(x: CDouble): CDouble = math.asin(x)
  def asin(x: CFloat): CFloat = math.asinf(x)
  def acos(x: CDouble): CDouble = math.acos(x)
  def acos(x: CFloat): CFloat = math.acosf(x)
  def atan(x: CDouble): CDouble = math.atan(x)
  def atan(x: CFloat): CFloat = math.atanf(x)
  def sinh(x: CDouble): CDouble = math.sinh(x)
  def sinh(x: CFloat): CFloat = math.sinhf(x)
  def cosh(x: CDouble): CDouble = math.cosh(x)
  def cosh(x: CFloat): CFloat = math.coshf(x)
  def tanh(x: CDouble): CDouble = math.tanh(x)
  def tanh(x: CFloat): CFloat = math.tanhf(x)
  def asinh(x: CDouble): CDouble = math.asinh(x)
  def asinh(x: CFloat): CFloat = math.asinhf(x)
  def atanh(x: CDouble): CDouble = math.atanh(x)
  def atanh(x: CFloat): CFloat = math.atanhf(x)
  // real only functions
  def atan2(y: CDouble, x: CDouble): CDouble = math.atan2(y, x)
  def atan2(y: CFloat, x: CFloat): CFloat = math.atan2f(y, x)
  def cbrt(x: CDouble): CDouble = math.cbrt(x)
  def cbrt(x: CFloat): CFloat = math.cbrtf(x)
  def ceil(x: CDouble): CDouble = math.ceil(x)
  def ceil(x: CFloat): CFloat = math.ceilf(x)
  def copysign(x: CDouble, y: CDouble): CDouble = math.copysign(x, y)
  def copysign(x: CFloat, y: CFloat): CFloat = math.copysignf(x, y)
  def erf(x: CDouble): CDouble = math.erf(x)
  def erf(x: CFloat): CFloat = math.erff(x)
  def erfc(x: CDouble): CDouble = math.erfc(x)
  def erfc(x: CFloat): CFloat = math.erfcf(x)
  def exp2(x: CDouble): CDouble = math.exp2(x)
  def exp2(x: CFloat): CFloat = math.exp2f(x)
  def expm1(x: CDouble): CDouble = math.expm1(x)
  def expm1(x: CFloat): CFloat = math.expm1f(x)
  def fdim(x: CDouble, y: CDouble): CDouble = math.fdim(x, y)
  def fdim(x: CFloat, y: CFloat): CFloat = math.fdimf(x, y)
  def floor(x: CDouble): CDouble = math.floor(x)
  def floor(x: CFloat): CFloat = math.floorf(x)
  def fma(x: CDouble, y: CDouble, z: CDouble): CDouble = math.fma(x, y, z)
  def fma(x: CFloat, y: CFloat, z: CFloat): CFloat = math.fmaf(x, y, z)
  def fmax(x: CDouble, y: CDouble): CDouble = math.fmax(x, y)
  def fmax(x: CFloat, y: CFloat): CFloat = math.fmaxf(x, y)
  def fmin(x: CDouble, y: CDouble): CDouble = math.fmin(x, y)
  def fmin(x: CFloat, y: CFloat): CFloat = math.fminf(x, y)
  def fmod(x: CDouble, y: CDouble): CDouble = math.fmod(x, y)
  def fmod(x: CFloat, y: CFloat): CFloat = math.fmodf(x, y)
  def frexp(arg: CDouble, exp: Ptr[CInt]): CDouble = math.frexp(arg, exp)
  def frexp(arg: CFloat, exp: Ptr[CInt]): CFloat = math.frexpf(arg, exp)
  def hypot(x: CDouble, y: CDouble): CDouble = math.hypot(x, y)
  // hypotf is available since c++17
  def hypot(x: CFloat, y: CFloat): CFloat = math.hypotf(x, y)
  def ilogb(x: CDouble): CInt = math.ilogb(x)
  def ilogb(x: CFloat): CInt = math.ilogbf(x)
  def ldexp(arg: CDouble, exp: CInt): CDouble = math.ldexp(arg, exp)
  // ldexpf is available since c++17
  def ldexp(arg: CFloat, exp: CInt): CFloat = math.ldexpf(arg, exp)
  def lgamma(x: CDouble): CDouble = math.lgamma(x)
  // lgammaf is available since c++17
  def lgamma(x: CFloat): CFloat = math.lgammaf(x)
  def llrint(x: CDouble): CLongLong = math.llrint(x)
  def llrint(x: CFloat): CLongLong = math.llrintf(x)
  def llround(x: CDouble): CLongLong = math.llround(x)
  def llround(x: CFloat): CLongLong = math.llroundf(x)
  def log10(x: CDouble): CDouble = math.log10(x)
  def log10(x: CFloat): CFloat = math.log10f(x)
  def log1p(x: CDouble): CDouble = math.log1p(x)
  def log1p(x: CFloat): CFloat = math.log1pf(x)
  def log2(x: CDouble): CDouble = math.log2(x)
  def log2(x: CFloat): CFloat = math.log2f(x)
  def logb(x: CDouble): CDouble = math.logb(x)
  def logb(x: CFloat): CFloat = math.logbf(x)
  def lrint(x: CDouble): CLong = math.lrint(x)
  def lrint(x: CFloat): CLong = math.lrintf(x)
  def lround(x: CDouble): CLong = math.lround(x)
  def lround(x: CFloat): CLong = math.lroundf(x)
  def nearbyint(x: CDouble): CDouble = math.nearbyint(x)
  def nearbyint(x: CFloat): CFloat = math.nearbyintf(x)
  def nextafter(from: CDouble, to: CDouble): CDouble = math.nextafter(from, to)
  def nextafter(from: CFloat, to: CFloat): CFloat = math.nextafterf(from, to)
  // def nexttoward
  def remainder(x: CDouble, y: CDouble): CDouble = math.remainder(x, y)
  // // remainderf is available since C++17
  def remainder(x: CFloat, y: CFloat): CFloat = math.remainderf(x, y)
  def remquo(x: CDouble, y: CDouble, quo: Ptr[CInt]): CDouble =
    math.remquo(x, y, quo)
  def remquo(x: CFloat, y: CFloat, quo: Ptr[CInt]): CFloat =
    math.remquof(x, y, quo)
  def rint(x: CDouble): CDouble = math.rint(x)
  def rint(x: CFloat): CFloat = math.rintf(x)
  def round(x: CDouble): CDouble = math.round(x)
  def round(x: CFloat): CFloat = math.roundf(x)
  def scalbln(arg: CDouble, exp: CLong): CDouble = math.scalbln(arg, exp)
  def scalbln(arg: CFloat, exp: CLong): CFloat = math.scalblnf(arg, exp)
  def scalbn(arg: CDouble, exp: CInt): CDouble = math.scalbn(arg, exp)
  def scalbn(arg: CFloat, exp: CInt): CFloat = math.scalbnf(arg, exp)
  def tgamma(x: CDouble): CDouble = math.tgamma(x)
  def tgamma(x: CFloat): CFloat = math.tgammaf(x)
  def trunc(x: CDouble): CDouble = math.trunc(x)
  def trunc(x: CFloat): CFloat = math.truncf(x)

}
